package client

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"gin-epg/internal/app/common/util"
	"gin-epg/internal/app/dao"
	"gin-epg/internal/app/entity"
	"github.com/go-resty/resty/v2"
	"strconv"
	"time"
)

// BFGD 频道名称映射
var mapBfgd = map[string]string{
	"4200000488": "CCTV1",
	"4200000643": "北京卫视4K",
	"4200000116": "广西卫视",
	"4200000058": "辽宁卫视",
	"4200000610": "辽宁都市",
	"4200000077": "辽宁公共",
	"4200000076": "辽宁经济",
	"4200000070": "辽宁影视剧",
	"4200000075": "辽宁教育青少",
	"4200000611": "辽宁体育休闲",
	"4200000073": "辽宁生活",
	"4200000071": "辽宁北方",
	"4200000139": "家庭理财",
	"4200000636": "重温经典",
	"4200000059": "沈阳新闻综合",
	"4200000273": "大连新闻综合",
	"4200000274": "鞍山新闻综合",
	"4200000275": "抚顺新闻综合",
	"4200000312": "本溪新闻综合",
	"4200000276": "丹东新闻综合",
	"4200000277": "锦州新闻综合",
	"4200000278": "营口新闻综合",
	"4200000279": "阜新新闻综合",
	"4200000280": "辽阳新闻综合",
	"4200000281": "铁岭新闻综合",
	"4200000282": "朝阳新闻综合",
	"4200000283": "盘锦新闻综合",
	"4200000284": "葫芦岛新闻综合",
	// 更多键值对...
}

// 全部频道列表接口 curl --location 'http://slave.bfgd.com.cn/media/channel/get_list?accesstoken=R5F2408FEU3198804BK78052214IE73560DFP2BF4M340CE68V0Z339CBW1626D4D261E46FEA&pageidx=1&pagenum=100'
// HandleBfgdCron 处理 BFGD 节目单
func HandleBfgdCron(beforeDay, afterDay int) error {
	dao.Logger.Infof("handleBfgdCron start")
	source := "bfgd"

	client := resty.New()
	for key, value := range mapBfgd {
		dao.Logger.Infof("Key: %s, Value: %s", key, value)
		for dayOffset := -beforeDay; dayOffset <= afterDay; dayOffset++ {
			date := time.Now().AddDate(0, 0, dayOffset).Format("2006-01-02")
			dao.Logger.Infof(date)

			startTime := strconv.FormatInt(getDayFirstSecond(date), 10)
			endTime := strconv.FormatInt(getDayLastSecond(date), 10)
			url := fmt.Sprintf("http://slave.bfgd.com.cn/media/event/get_list?chnlid=%s&pageidx=1&vcontrol=0&attachdesc=1&repeat=1&accesstoken=R5F2408FEU3198804BK78052214IE73560DFP2BF4M340CE68V0Z339CBW1626D4D261E46FEA&starttime=%s&endtime=%s&pagenum=100&flagposter=0", key, startTime, endTime)
			proxyURL, err := util.GetConfigValue("proxy.proxyApiUrlBfgd")
			if err != nil {
				dao.Logger.Errorf("Error: %v", err)
			} else {
				dao.Logger.Infof("proxyApiUrlBfgd: %v", proxyURL)
				url = fmt.Sprintf("%s%s", proxyURL, url[len("http://slave.bfgd.com.cn"):])
			}

			resp, err := client.R().
				SetHeaders(map[string]string{
					"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
				}).
				Get(url)

			if err != nil {
				return fmt.Errorf("failed to get data from URL: %v", err)
			}

			var data map[string]interface{}
			if err := json.Unmarshal(resp.Body(), &data); err != nil {
				return fmt.Errorf("failed to unmarshal JSON: %v", err)
			}

			if eventList, ok := data["event_list"].([]interface{}); ok {
				// 获取当前日期范围内的已有节目记录
				db := dao.SqlSession
				dateParsed, _ := time.Parse("2006-01-02", date)
				var existingRecords []entity.EpgProgramCollect
				if err := db.Where(&entity.EpgProgramCollect{Channel: value, Date: entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}}, Source: source}).Find(&existingRecords).Error; err != nil {
					dao.Logger.Errorf("failed to get existing records: %v", err)
					continue
				}

				existingMap := make(map[string]*entity.EpgProgramCollect)
				for i := range existingRecords {
					existingMap[existingRecords[i].Start] = &existingRecords[i]
				}

				var newPrograms, updatePrograms, deletePrograms []entity.EpgProgramCollect

				for _, event := range eventList {
					eventMap := event.(map[string]interface{})
					startDate := int64(eventMap["start_time"].(float64))
					momentStartDate := time.Unix(startDate, 0)
					stopDate := int64(eventMap["end_time"].(float64))
					momentStopDate := time.Unix(stopDate, 0)

					channel := value
					dateStr := momentStartDate.Format("2006-01-02")
					start := momentStartDate.Format("15:04")
					stop := momentStopDate.Format("15:04")

					if channel != "" && dateStr != "" && start != "" && stop != "" {
						if dateStr == date {
							title := eventMap["event_name"].(string)
							desc := eventMap["desc"].(string)

							if existingRecord, ok := existingMap[start]; ok {
								if existingRecord.Title != title || existingRecord.End != stop {
									existingRecord.Title = title
									existingRecord.Desc = desc
									existingRecord.End = stop
									existingRecord.UpdateTime = entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}}
									updatePrograms = append(updatePrograms, *existingRecord)
								}
								delete(existingMap, start)
							} else {
								newRecord := entity.EpgProgramCollect{
									Title:      title,
									Desc:       desc,
									Source:     source,
									Channel:    channel,
									Date:       entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}},
									Start:      start,
									End:        stop,
									CreateTime: entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}},
								}
								newPrograms = append(newPrograms, newRecord)
							}
						}
					}
				}

				// 处理需要删除的记录
				for _, record := range existingMap {
					deletePrograms = append(deletePrograms, *record)
				}

				// 执行数据库操作
				if len(updatePrograms) > 0 {
					for _, program := range updatePrograms {
						if err := db.Model(&program).Updates(entity.EpgProgramCollect{Title: program.Title, Desc: program.Desc, End: program.End, UpdateTime: program.UpdateTime}).Error; err != nil {
							dao.Logger.Errorf("update error: %v", err)
						} else {
							dao.Logger.Debugf("update success: %v", program)
						}
					}
				}

				if len(newPrograms) > 0 {
					for _, program := range newPrograms {
						if err := db.Create(&program).Error; err != nil {
							dao.Logger.Errorf("insert error: %v", err)
						} else {
							dao.Logger.Debugf("insert success: %v", program)
						}
					}
				}

				if len(deletePrograms) > 0 {
					for _, program := range deletePrograms {
						if err := db.Delete(&program).Error; err != nil {
							dao.Logger.Errorf("delete error: %v", err)
						} else {
							dao.Logger.Debugf("delete success: %v", program)
						}
					}
				}
			}
		}
	}
	return nil
}

// getDayFirstSecond 获取指定日期的第一秒时间戳
func getDayFirstSecond(dateStr string) int64 {
	date, _ := time.Parse("2006-01-02", dateStr)
	return time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location()).Unix()
}

// getDayLastSecond 获取指定日期的最后一秒时间戳
func getDayLastSecond(dateStr string) int64 {
	date, _ := time.Parse("2006-01-02", dateStr)
	return time.Date(date.Year(), date.Month(), date.Day(), 23, 59, 59, 0, date.Location()).Unix()
}
